package com.example.myapplication.mylivedata;

import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 解决数据粘性问题
 * @param <T>
 */
public class NonStickyMutableLiveData<T> extends MutableLiveData<T> {

    private boolean stickFlag = false;

    // 观察的行为  做事情  TODO    HOOK
    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        super.observe(owner, observer);

        if (!stickFlag) {
         hook(observer);
        }
    }

    private void hook(Observer<? super T> observer) {

        Class<LiveData> liveDataClass = LiveData.class;
        try {
            Field mObservers = liveDataClass.getDeclaredField("mObservers");
            mObservers.setAccessible(true);
            //获取集合 SatfeIterableMap
            Object observers = mObservers.get(this);
            //得到map对应的class
            Class<?> observersClass = observers.getClass();
            //获取 SatfeIterableMap 的  get(Object obj) 方法
            Method methodGet = observersClass.getDeclaredMethod("get", Object.class);
            methodGet.setAccessible(true);
            // 执行 get 方法
            Object objectWrapperEntry = methodGet.invoke(observers, observer);
            Object objectWrapper = null;
            if (objectWrapperEntry instanceof Map.Entry){
                objectWrapper = ((Map.Entry<?, ?>) objectWrapperEntry).getValue();
            }
            if (objectWrapper == null) {
                throw new NullPointerException("ObjectWrapper can not be null");
            }
            //  获取  ObjectWrapper  的 class  对象    LifecycleBoundObserver extends ObserverWrapper
            Class<?> wrapperclass = objectWrapper.getClass().getSuperclass();
            //   获取  objectWrapper  的  field mLastVersion
            Field mLastVersion = wrapperclass.getDeclaredField("mLastVersion");
            mLastVersion.setAccessible(true);
            //  获取  LiveData  的   mVersion
            Field mVersion = LiveData.class.getDeclaredField("mVersion");
            mVersion.setAccessible(true);
            Object mV = mVersion.get(this);
            //  TODO  最关键的一句话   让  mLastVersion  与 mVersion   条件相等
            //  把当前LiveData  的 mVersion 赋值给  ObjectWrapper  的  mLastVersion
            mLastVersion.set(objectWrapper,mV);
            stickFlag = true;
            mObservers.setAccessible(false);
            methodGet.setAccessible(false);
            mLastVersion.setAccessible(false);
            mVersion.setAccessible(false);
        } catch (Exception e) {
            Log.e("Derry","observe:  HOOK  发生了异常 "  + e.getMessage());
            e.printStackTrace();
        }
    }

}
